package com.flyfinger.rpcserver;

import com.flyfinger.codec.RpcDecoder;
import com.flyfinger.codec.RpcEncoder;
import com.flyfinger.codec.impl.JSONSerializer;
import com.flyfinger.pojo.ServiceLocation;
import com.flyfinger.register.CuratorClient;
import com.flyfinger.rpcserver.lagou.handler.UserServiceHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class ServerBootstrap {

	public static void main(String[] args) throws Exception {
		int port = 9000;
		if (args.length != 0){
			port = Integer.parseInt(args[0]);
		}

		int finalPort = port;
		Runtime.getRuntime().addShutdownHook(new Thread() {
			@Override
			public void run() {
				System.out.printf("====关闭[%s]提供的服务=======", finalPort);
			}
		});

		final ConfigurableApplicationContext run = SpringApplication.run(ServerBootstrap.class, args);

		final UserServiceHandler handler = run.getBean(UserServiceHandler.class);

		final CuratorFramework client = CuratorClient.curator();
		client.start();

		final ServiceLocation location = new ServiceLocation("127.0.0.1", port);

		startServer(handler, port);

		client.create()
				.creatingParentContainersIfNeeded()
				.withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
				.forPath(CuratorClient.ZK_CLIENT_PATH + "/info",
						location.writeAsBytes());
	}

	public static void startServer(UserServiceHandler handler, int port) throws InterruptedException {
		handler.setPort(port);

		NioEventLoopGroup bossGroup = new NioEventLoopGroup();
		NioEventLoopGroup workGroup = new NioEventLoopGroup();

		new io.netty.bootstrap.ServerBootstrap().group(bossGroup, workGroup)
				.channel(NioServerSocketChannel.class)
				.childHandler(new ChannelInitializer<NioSocketChannel>() {
					protected void initChannel(NioSocketChannel nioSocketChannel) {
						ChannelPipeline pipeline = nioSocketChannel.pipeline();
						pipeline.addFirst(new RpcDecoder(JSONSerializer.getInstance()));
						pipeline.addLast(new RpcEncoder(JSONSerializer.getInstance()));
						pipeline.addLast(handler);
					}
				})
				.bind(port).sync();
	}

}
